package gate_app;

import gate.*;
import gate.creole.*;
import gate.creole.ir.DefaultIndexDefinition;
import gate.creole.ir.DocumentContentReader;
import gate.creole.ir.IndexField;
import gate.creole.ir.IndexedCorpus;
import gate.creole.ir.QueryResult;
import gate.creole.ir.QueryResultList;
import gate.creole.ir.Search;
import gate.creole.ir.lucene.LuceneSearch;
import gate.util.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class GATE {
    
    //Thu muc goc
    private static String ROOT = "C:/gate-7-2/GATE/";
    
    //Thư mục lưu trữ index
    private static String INDEX_LOCATION = ROOT + "lucene";

    //Thư mục lưu trữ datastore
    private static String SERIAL_DATASTORE_PATH = "file:///" + ROOT + "gate_corpus";
    //NOTE: Thư mục phải trống

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        GATE irApp = new GATE();
        
        //Khởi tạo GATE
        //    
        try {
          Gate.init();
          Out.prln("GATE initialised...");
        }
        catch (GateException gex) {
          Err.prln("cannot initialise GATE...");
          return;
        }
        
        try{
        //1. create and open a serial data store
        DataStore sds = Factory.createDataStore("gate.persist.SerialDataStore", SERIAL_DATASTORE_PATH);
        Out.prln("Datastore created...");
        sds.open();

        //2. create transient corpus with 2 docs (Document1 with 1.txt & Document 2 with 2.txt)
        Corpus corpus =  irApp.createTestCorpus();

        //3. serialize corpus in Serial datastore
        Corpus serialCorpus = (Corpus)sds.adopt(corpus,null);

        //4. sync datastore
        sds.sync(serialCorpus);

        //5. index the serialized corpus
        IndexedCorpus indexedCorpus = (IndexedCorpus)serialCorpus;


        //Khởi tạo Index 
        DefaultIndexDefinition did = new DefaultIndexDefinition();
        // Sử dụng kỹ thuật Lucene IR
        //  
        did.setIrEngineClassName(gate.creole.ir.lucene.LuceneIREngine.class.getName());

        //Xác định vị trí index
        did.setIndexLocation(INDEX_LOCATION);

        //Xác định trường index
        did.addIndexField(new IndexField("content", new DocumentContentReader(), false));

        indexedCorpus.setIndexDefinition(did);

        //5.5 ask the IndexManager to create the index (delete it beforehand if already existing)
        indexedCorpus.getIndexManager().deleteIndex();
        indexedCorpus.getIndexManager().createIndex();
        indexedCorpus.getIndexManager().optimizeIndex();

        //7. search in index

        //7.2.  create the proper Search subclass
        //    since we're using the Lucene IR engine, use LuceneSearch
        Search search = new LuceneSearch();
        //    the Search instance needs to know which corpus to search
        search.setCorpus(indexedCorpus);

        String q = "";
        while(!q.equals("exit"))
        {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            Out.print("query> ");
            q = br.readLine();
            String query = "content:\"" + q + "\"";
            //    ...Câu truy vấn tìm kiếm trong nội dung tài liệu

            irApp.timKiem(sds, search, query);
        }

        Out.prln("done...");

      }
      catch(Exception ex) {
        ex.printStackTrace(Err.getPrintWriter());
      }
    }
    
    public void timKiem(DataStore sds, Search search, String query)
    {
        try
        {
        //Thực thi câu truy vấn
        QueryResultList res = search.search(query);
        //Trả về kết quả
        Iterator it = res.getQueryResults();
        //Xem kết quả
        while (it.hasNext()) {
          QueryResult qr = (QueryResult) it.next();
          float score = qr.getScore();
          //
          //  Lấy thông tin về tài liệu liên quan
          Document resultDoc = (Document) sds.getLr("gate.corpora.DocumentImpl", qr.getDocumentID());
          Out.prln("Query: Tên tài liệu = " + resultDoc.getName());
          Out.prln("Query: Tần suất xuất hiện  = " + score);

          // Output kết quả tìm kiếm ra file XML, lưu tại project thực thi
          FileWriter writer = new FileWriter( ROOT + "result/" + resultDoc.getName()+ ".xml");
          writer.write(resultDoc.toXml());
          writer.close();

          Out.prln("------------");
        }
        }
        catch(Exception ex)
        {
            ex.printStackTrace(Err.getPrintWriter());
        }
    }
      
  
  public Corpus createTestCorpus()
    throws MalformedURLException, ResourceInstantiationException {

    Document doc1 = Factory.newDocument(new URL("file:///" + ROOT + "document/1.txt"));
    doc1.setName("Document 1");

    Document doc2 = Factory.newDocument(new URL("file:///" + ROOT + "document/2.txt"));
    doc2.setName("Document 2");
    
    Document doc3 = Factory.newDocument(new URL("file:///" + ROOT + "document/3.txt"));
    doc3.setName("Document 3");

    Document doc4 = Factory.newDocument(new URL("file:///" + ROOT + "document/4.txt"));
    doc4.setName("Document 4");

    //Tạo 1 corpus với những tài liệu trên
    Corpus result = Factory.newCorpus("test corpus");
    assert result != null;
    result.add(doc1);
    result.add(doc2);
    result.add(doc3);
    result.add(doc4);

    return result;
  }
}
